package com.wms.service;

import com.mes.entity.User;
import com.yy.base.common.dao.Dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 收货确认
 * @author ZT
 */
@Service
@SuppressWarnings("unchecked")
public class OutConfirmService {
	@Autowired
	private Dao dao;

	/**
	 * 根据单据编码查询单据出库列表
	 * @param code
	 * @return
	 */
	public List<Map<String, Object>> getOrderOutList(String code) {
		List<Map<String, Object>> list = null;
		String sql = "select lmx.m_product_id, p.value pcode, p.name pname, io.qty, sb.batch_no, " +
				"		lmx.Wms_Material_List_L_Mx_Id mxId, l.Wms_Material_List_Head_Id orderId, io.Wms_Storage_In_Out_Id," +
				"       (select value from M_Locator lo where lo.M_Locator_Id = io.M_Locator_Id) locator, 'Wms_Material_List_L_Mx' as type" +
				"  from M_Product p, Wms_Storage_Batch sb, Wms_Storage_In_Out io, Wms_Material_List_L_Mx lmx, Wms_Material_List_Head l" +
				" where p.m_product_id = lmx.m_product_id " +
				"	and sb.Wms_Storage_Batch_Id = io.Wms_Storage_Batch_Id" +
				"   and io.status = 'LOCKED'" +
				"   and io.data_id = lmx.Wms_Material_List_L_Mx_Id" +
				"   and lmx.Wms_Material_List_Head_Id = l.Wms_Material_List_Head_Id" +
				"   and l.code = ?";
		list = dao.query(sql, code);
		if (list == null || list.isEmpty()) {
			sql = "select mh.m_product_id, p.value pcode, p.name pname, io.qty, sb.batch_no," +
					"		mh.Wms_Put_M_Formal_Hz_Id mxId, mf.Wms_Put_M_Formal_Id orderId, io.Wms_Storage_In_Out_Id, " +
					"       (select value from M_Locator lo where lo.M_Locator_Id = io.M_Locator_Id) locator, 'Wms_Put_M_Formal_Hz' as type" +
					"  from M_Product p, Wms_Storage_Batch sb, Wms_Storage_In_Out io, Wms_Put_M_Formal_Hz mh, Wms_Put_M_Formal mf " +
					" where p.m_product_id = mh.m_product_id " +
					"	and sb.Wms_Storage_Batch_Id = io.Wms_Storage_Batch_Id" +
					"   and io.data_id = mh.Wms_Put_M_Formal_Hz_Id" +
					"   and io.status = 'LOCKED'" +
					"   and mh.Wms_Put_M_Formal_Id = mf.Wms_Put_M_Formal_Id" +
					"   and mf.code = ?";
			list = dao.query(sql, code);
		}
		if (list == null || list.isEmpty()) {
			sql = "select mx.m_product_id, p.value pcode, p.name pname, io.qty, sb.batch_no,mx.wms_call_put_m_mx_id mxId, pm.wms_call_put_m_id pmId, io.Wms_Storage_In_Out_Id ioid,(select value from M_Locator lo where lo.M_Locator_Id = io.M_Locator_Id) locator    " + 
					"from M_Product p, Wms_Storage_Batch sb, Wms_Storage_In_Out io, Wms_Call_Put_M_MX mx, Wms_Call_Put_M pm  " + 
					"where p.m_product_id = mx.m_product_id  " + 
					"and sb.Wms_Storage_Batch_Id = io.Wms_Storage_Batch_Id   " + 
					"and io.data_id = mx.Wms_Call_Put_M_MX_id " + 
					"and io.status = 'LOCKED'  " + 
					"and pm.wms_call_put_m_id = mx.wms_call_put_m_id  " + 
					"and pm.code= ?";
			list = dao.query(sql, code);
		}
		
		return list;
	}
	/**
	 * 出库单确认出库，修改锁定状态
	 */
	public String outStorageConfirm(List<Map<String, Object>> list, String[] ids, String[]qtys, User user) {
		String sql = "update Wms_Storage_In_Out set status = 'OK', qty = ?, updated = now() where Wms_Storage_In_Out_ID = ? ";
		String qtyOutName = "qty_Out";
		if ("Wms_Put_M_Formal_Hz".equalsIgnoreCase((String)list.get(0).get("TYPE"))) {
			qtyOutName = "ACT_QTY";
		}
		Map<String, Double> outMap = new HashMap<String, Double>();
		for (int i = 0; i < ids.length; i++) {
			outMap.put(ids[i], Double.parseDouble(qtys[i]));
		}
		
		double qty = 0;
		double lockQty = 0;
		for (Map<String, Object> map : list) {
			qty = outMap.get(map.get("WMS_STORAGE_IN_OUT_ID"));
			lockQty = Math.abs(Double.parseDouble(map.get("QTY").toString()));
			
			if (qty < 0) {
				return map.get("M_PRODUCT_ID") + "批次" + map.get("BATCH_NO") + "出库数量不能为0或负数！";
			}
			if (qty > lockQty) {
				return map.get("M_PRODUCT_ID") + "批次" + map.get("BATCH_NO") + "不能多于需求数量：" + lockQty;
			}
			if (qty == 0) {
				//当发货数量为0，则将此出库记录设置为取消
				dao.executeSql("update WMS_STORAGE_IN_OUT set status = 'CANCEL', updated = now() where WMS_STORAGE_IN_OUT_ID = ?", map.get("WMS_STORAGE_IN_OUT_ID"));
			} else {
				//将状态修改为完成
				dao.executeSql(sql, -qty, map.get("WMS_STORAGE_IN_OUT_ID"));
			}
			
			dao.executeSql("update " + map.get("TYPE") + " set " + qtyOutName + " = NVL(" + qtyOutName + ", 0) + ? where " + 
					map.get("TYPE") + "_Id = ?", qty, map.get("MXID"));
			
			//将出库数量修改到领料单明细的已生产正式数量（未发料的数量还可以继续生成领料单重新领料）
			if ("Wms_Put_M_Formal_Hz".equalsIgnoreCase((String)map.get("TYPE"))) {
				dao.executeSql("update Wms_Put_Material_Hz mh " +
						"set Qty_Out = nvl(Qty_Out, 0) + ?, Qty_Create = nvl(Qty_Create, 0) - ? " +
						"where exists (" +
						"	select 1 from Wms_Put_M_Formal_Hz fh " +
						"	 where fh.Wms_Put_Material_Hz_Id = mh.Wms_Put_Material_Hz_Id " +
						"  	   and fh.Wms_Put_M_Formal_Hz_Id = ?)", qty, (lockQty - qty), map.get("MXID"));
				
				//修改正是领料单的备料人，领料时间
				dao.executeSql("update Wms_Put_M_Formal set Admin_User = ?, Take_Date = now() " +
						"where Admin_User is null and Wms_Put_M_Formal_Id = ?", user.getId(), map.get("ORDERID"));
				
				//回写到MES的领料申请单中
//				if ("scly".equalsIgnoreCase((String)map.get("OUT_TYPE"))) {
//					String code = (String) map.get("CODE");
//					if ("C4".equals(code.substring(3, 5))) {
//						String updateMesSql = "update MES.EMESO_MANU_OM_STORAGE set qty = (qty+?) where M_PRODUCT_ID = ? and ad_org_id = '4BAD2EB3B9B844FAABCDDD744E529F55'";
//						dao.executeSql(updateMesSql, qty,map.get("M_PRODUCT_ID"));
//					} else {
//						String updateMesSql = "update MES.EMESO_MANU_OM_STORAGE set qty = (qty+?) where M_PRODUCT_ID = ? and ad_org_id = '7B441EB01848477687A8ADE94F1F5F2A'";
//						dao.executeSql(updateMesSql, qty,map.get("M_PRODUCT_ID"));
//					}
//				}
			//其他出库修改出库数量，状态
			} else if ("Wms_Material_List_L_Mx".equalsIgnoreCase((String)map.get("TYPE"))) {
				dao.executeSql("update Wms_Material_List_Mx mx set Qty_Out = nvl(Qty_Out, 0) - ? " +
						"where mx.Wms_Material_List_Mx_Id = ?", (lockQty - qty), map.get("MXID"));
				
				//修改正是领料单的备料人，备料时间
				dao.executeSql("update Wms_Material_List_Head set Prepare_User = ?, Prepare_Date = now(), status = 'YBL' " +
						"where Prepare_User is null and Wms_Material_List_Head_Id = ?", user.getId(), map.get("ORDERID"));
				//呼叫投料出库
			} else if ("Wms_Call_Put_M_MX".equalsIgnoreCase((String)map.get("TYPE"))) {
				dao.executeSql("update Wms_Ready_Material_Hz hz " +
						"set Qty_Out = nvl(Qty_Out, 0) + ? " +
						"where exists (" +
						"	select 1 from Wms_Call_Put_M_MX mx " +
						"	 where mx.Wms_Ready_Material_Hz_Id = hz.Wms_Ready_Material_Hz_Id " +
						"  	   and mx.Wms_Call_Put_M_MX_Id = ?)", qty, map.get("MXID"));
				
				dao.executeSql("update Wms_Call_Put_M_MX set Admin_User = ? " +
						"where Admin_User is null and Wms_Call_Put_M_MX_Id = ?", user.getId(), map.get("MXID"));
			}
		}
		updateOrderStatus();
		return null;
	}
	
	// 调用出库单的状态(可以将所有单据的更新都放到这个存储过程)
	public void updateOrderStatus() {
		dao.callSql("{ call Wms_Change_Order_Status() }");
	}
}